import { bearing, distance } from '@/geom/great-circle'
import { getEntityMap } from '../../base'
import type { Waypoint } from '../../waypoint'
import { type Routing, type RoutingSegment } from '../types'
import { getAirportRoutingSet, getWaypointRoutingSet } from '../routing-index'

export interface RoutingSegmentInfo {
  start: string
  end: string
  length: number
  course: number
  atsRoute: string | null
}

export interface RoutingInfo {
  id: string
  length: number
  departureAirport: string | null
  arrivalAirport: string | null
  segmentList: RoutingSegmentInfo[]
}

const routingInfos: Record<string, RoutingInfo> = {}

function makeRoutingInfo(r: Routing): RoutingInfo {
  const wpts = getEntityMap<Waypoint>('Waypoint')
  const segmentList = r.segmentList.map((e) => segmentInfo(e, wpts))
  let length = 0
  for (const seg of segmentList) {
    length += seg.length
  }
  return {
    id: r.id,
    length,
    departureAirport: r.departureAirport || null,
    arrivalAirport: r.arrivalAirport || null,
    segmentList
  }
}

export function setupRoutingInfos(rLst: Routing[]) {
  for (const r of rLst) {
    routingInfos[r.id] = makeRoutingInfo(r)
  }
}

export function getRoutingInfo(r: Routing): RoutingInfo {
  let info = routingInfos[r.id]
  if (!info) {
    info = makeRoutingInfo(r)
    routingInfos[r.id] = info
  }
  return info
}

function segmentInfo(s: RoutingSegment, wpts: Record<string, Waypoint>): RoutingSegmentInfo {
  const wpt0 = wpts[s.start]
  const wpt1 = wpts[s.end]
  let course = bearing(wpt0.location, wpt1.location)
  if (course < 0) {
    course += 360
  }
  return {
    start: s.start,
    end: s.end,
    length: distance(wpt0.location, wpt1.location),
    course,
    atsRoute: s.atsRoute || null
  }
}

export function getWaypointRoutingInfoList(wpt: string): RoutingInfo[] {
  const s = getWaypointRoutingSet(wpt)
  if (!s) {
    return []
  }
  const ret: RoutingInfo[] = []
  for (const r of s) {
    ret.push(getRoutingInfo(r))
  }
  return ret
}

export function getAirportRoutingInfoList(apt: string): RoutingInfo[] {
  const s = getAirportRoutingSet(apt)
  if (!s) {
    return []
  }
  const ret: RoutingInfo[] = []
  for (const r of s) {
    ret.push(getRoutingInfo(r))
  }
  return ret
}
